﻿using AForge.Imaging.Filters;
using BoardBroker;
using ComLib.ComType;
using ComUIControl;
using CoreBroker;
using KWindow.KPageCore;
using LogLib;
using PhotoNamingService;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;

namespace IPCPages
{
    public partial class PagePickoutPhoto : PageControlBase
    {
        private BoardControl _board = BoardControl.Instance;
        private BaseResizeFilter _resizefilter = null;  
        private Dictionary<RadioButton, PictureBox> dicMapToPic = new Dictionary<RadioButton, PictureBox>();
        private Dictionary<PictureBox, TakenPhoto> dicMapToPhoto = new Dictionary<PictureBox, TakenPhoto>();
        private List<TakenPhoto> listPassPhotos = new List<TakenPhoto>();
        private List<TakenPhoto> listUnPassPhotos = new List<TakenPhoto>();
        private List<RadioButton> listRadioButtons = new List<RadioButton>();
        private PhotoTakenResult takenResultType = PhotoTakenResult.Success;
        private Button buttonOK = null;    
        private Button buttonRetake = null;
        private PictureBox pictureBox1 = null;
        private PictureBox pictureBox2 = null;
        private PictureBox pictureBoxPass = null;
        private PictureBox pictureBoxNoPass = null;
        private Label label3 = null;
        private Label labelReason = null;
        private Label labelDetRes1 = null;
        private Label labelDetRes2 = null;
        private IDCardAll _cardInfo = null;
        public PagePickoutPhoto()
        {
            try
            {               
                _resizefilter = new ResizeBilinear(1000, 1200);
                InitializeComponent();
                SetProcessBase(ProcessPickOutPhoto.Instance);
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
                MsgBox.Show(ex.ToString());             
            }                
        }

        private void GetControls()
        {
            try
            {
                buttonOK = GetControl<Button>("buttonOK") as Button;
                buttonCancel = GetControl<Button>("buttonCancel") as Button;
                buttonRetake = GetControl<Button>("buttonRetake") as Button;

                SetButtonDefaultStyles(buttonOK);
                SetButtonDefaultStyles(buttonCancel);
                SetButtonDefaultStyles(buttonRetake);

                pictureBox1 = GetControl<PictureBox>("pictureBox1") as PictureBox;
                pictureBox2 = GetControl<PictureBox>("pictureBox2") as PictureBox;

                pictureBoxPass = GetControl<PictureBox>("pictureBoxPass") as PictureBox;
                pictureBoxNoPass = GetControl<PictureBox>("pictureBoxNoPass") as PictureBox;

                label3 = GetControl<Label>("label3") as Label;
                labelReason = GetControl<Label>("labelReason") as Label;
                labelDetRes1 = GetControl<Label>("labelDetRes1") as Label;
                labelDetRes2 = GetControl<Label>("labelDetRes2") as Label;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                Log.WriteException(ex.ToString());
            }        
        }

        public override void InitCtrls()
        {
            if (Initialized)
            {
                return;
            }
            dicMapToPic.Clear();
            base.InitCtrls();
            GetControls();
            listRadioButtons.Add(radioButton1);
            listRadioButtons.Add(radioButton2);
          
            dicMapToPic.Add(radioButton1, pictureBox1);
            dicMapToPic.Add(radioButton2, pictureBox2);

            pictureBoxPass.Location = new Point(0, 0);
            pictureBoxPass.Size = pictureBox1.Size;
            pictureBoxPass.Image = Properties.Resources.check;
            pictureBoxPass.Visible = false;

            pictureBoxPass.Location = new Point(0, 0);
            pictureBoxPass.Size = pictureBox1.Size;
            pictureBoxPass.Image = Properties.Resources.check;
            pictureBoxPass.Visible = false;

            label3.Visible = false;
            labelReason.Visible = false;
        }

        public override void InitData()
        {
            base.InitData();
            dicMapToPhoto.Clear();
            buttonOK.Enabled = true;
            _cardInfo = Process.GetValue<IDCardAll>("IDCardInfo");
            takenResultType = Process.GetValue<PhotoTakenResult>("PhotoTakenResult");
            listPassPhotos = Process.GetValue<List<TakenPhoto>>("TakenPhotos");
            listUnPassPhotos = Process.GetValue<List<TakenPhoto>>("NoPassPhotos");
            if(listPassPhotos == null)
            {
                Log.WriteAsync("获取拍照结果照片为空!");
                MsgBox.Show("意外的错误:\n获取拍照结果照片为空!");
                return;
            }
            InitPictureBox();           
        }

        public override void ClearData()
        {
            base.ClearData();           
            if(pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }
            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
                pictureBox2.Image = null;
            }
            if (listPassPhotos != null)
            {
                for (int i = 0; i < listPassPhotos.Count; i++)
                {
                    if (listPassPhotos[i] != null)
                    {
                        listPassPhotos[i].Dispose();
                        listPassPhotos[i] = null;
                    }
                }
            }
            if (listUnPassPhotos != null)
            {
                for (int i = 0; i < listUnPassPhotos.Count; i++)
                {
                    if (listUnPassPhotos[i] != null)
                    {
                        listUnPassPhotos[i].Dispose();
                        listUnPassPhotos[i] = null;
                    }
                }
            }         
        }

        public override void UpdateData()
        {
            TakenPhoto photo = null;
            if (radioButton1.Checked && !radioButton2.Checked)
            {
                PictureBox pic = dicMapToPic[radioButton1];
                photo = dicMapToPhoto[pic];
            }
            if (!radioButton1.Checked && radioButton2.Checked)
            {
                PictureBox pic = dicMapToPic[radioButton2];
                photo = dicMapToPhoto[pic];
            }
            if (!radioButton1.Checked && !radioButton2.Checked)
            {
                throw new Exception("用户没有选中任何照片, 请点击屏幕选中一张照片.");
            }
            if (radioButton1.Checked && radioButton2.Checked)
            {
                throw new Exception("发生了异常, radioButton1.Checked && radioButton2.Checked = true");
            }

            TakenPhoto OnlyPhoto = photo.Clone() as TakenPhoto;
            //保存选中的照片
            Process.SetValue("TakenPhoto", OnlyPhoto);
            Process.SetValue("ZZZPPath", OnlyPhoto.DestImagePath);
            string inParams = "";
            IDCardAll info = Process.GetValue<IDCardAll>("IDCardInfo");
            if(info != null)
            {
                inParams = info.number;
            }

            string srcFile = OnlyPhoto.DestImagePath;
            string serialNumber = _config.CreatSerialNumber(inParams);
            Log.WriteAsync($"生成照片序列号:{serialNumber}");
            // 生成照片序列号
            SD.SetValue("PhotoSerialNumber", serialNumber);
            string personDir = _config.OutputDirs[serialNumber];
            Process.SetValue("PersonDataDirectory", personDir);
            string fileName = serialNumber + ".jpg";
            string destFile = Path.Combine(personDir, fileName);

            if (!PhotoNamingBase.Option.EnableOverride)
            {
                if (File.Exists(destFile))
                {
                    throw new Exception("已存在同名照片。由于设置了不可覆盖，本次保存被取消。\n如果需要继续正常使用，请联系管理员修改操作选项。");
                }
            }           
            try
            {
                File.Copy(srcFile, destFile, true);
                Log.WriteAsync("制证照片已保存到个人数据目录:" + destFile);
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
                string error = "复制文件发生了异常:\n" + ex.Message;
                MessageBox.Show(error);
            }

            // 保存现场人像
            if(UserAction == UserApplyAction.TakePhotoAndWeiYinTB 
                || UserAction == UserApplyAction.TakePhotoAndYSL)
            {
                try
                {
                    string liveportraitFile = Path.Combine(personDir, "LivePortrait.jpg");
                    //Bitmap liveportraitImage = _resizefilter.Apply(OnlyPhoto.SourceImage);
                    // liveportraitImage.Save(liveportraitFile, ImageFormat.Jpeg);
                    File.Copy(OnlyPhoto.SourceImagePath, liveportraitFile);
                    Log.WriteAsync("现场人像照片已保存到个人数据目录:" + liveportraitFile);
                    //liveportraitImage.Dispose();
                   // liveportraitImage = null;                  
                    Process.SetValue("Liveportrait", liveportraitFile);
                }
                catch (Exception ex)
                {
                    Log.WriteException(ex.ToString());
                    string error = "保存现场人像照片发生了异常:\n" + ex.Message;
                    MessageBox.Show(error);
                }               
            }
        }

        private void InitPictureBox()
        {
            if (takenResultType == PhotoTakenResult.Success)
            {
                if(listPassPhotos.Count != 2)
                {
                    throw new Exception("意外的错误: 拍照结果异常(listPassPhotos.Count!=2).");
                }

                labelDetRes1.Text = "合格";
                labelDetRes2.Text = "合格";
                label3.Visible = false;
                labelReason.Visible = false;
                if (!string.IsNullOrEmpty(listPassPhotos[0].DestImagePath) && File.Exists(listPassPhotos[0].DestImagePath))
                    pictureBox1.Image = Image.FromFile(listPassPhotos[0].DestImagePath);//listPassPhotos[0].DestImage;
                if (!string.IsNullOrEmpty(listPassPhotos[1].DestImagePath) && File.Exists(listPassPhotos[1].DestImagePath))
                    pictureBox2.Image = Image.FromFile(listPassPhotos[1].DestImagePath); //listPassPhotos[1].DestImage;
                dicMapToPhoto.Add(pictureBox1, listPassPhotos[0]);
                dicMapToPhoto.Add(pictureBox2, listPassPhotos[1]);

                pictureBoxPass.Visible = false;
                pictureBoxNoPass.Visible = false;
                radioButton1.Checked = false;
                radioButton2.Checked = false;

                SetSelectPhoto(0);
                return;
            }
            if (takenResultType == PhotoTakenResult.SomeFailed)
            {
                if (listPassPhotos.Count != 1)
                {
                    throw new Exception("意外的错误: 拍照结果异常(listPassPhotos.Count != 1).");
                }
                if (listUnPassPhotos.Count != 1)
                {
                    throw new Exception("意外的错误: 拍照结果异常(listUnPassPhotos.Count != 1).");
                }
                label3.Visible = true;
                labelReason.Visible = true;
                labelReason.Text = listUnPassPhotos[0].NotPassReason;

                // 第二张不合格
                if (listUnPassPhotos[0].Index == 1)
                {
                    labelDetRes1.Text = "合格";
                    labelDetRes2.Text = "不合格";
                    int x1 = pictureBox2.Left;
                    int y = labelDetRes2.Bottom + 5;
                    Log.WriteAsync($"labelDetRes2:({labelDetRes2.Left},{labelDetRes2.Top},{labelDetRes2.Right},{labelDetRes2.Bottom})");
                    label3.Location = new Point(x1, y);
                    int x2 = label3.Right;
                    labelReason.Location = new Point(x2, y);
                    Log.WriteAsync($"labelReason:({labelReason.Left},{labelReason.Top},{labelReason.Right},{labelReason.Bottom})");
                    if(!string.IsNullOrEmpty(listPassPhotos[0].DestImagePath) && File.Exists(listPassPhotos[0].DestImagePath))
                        pictureBox1.Image = Image.FromFile(listPassPhotos[0].DestImagePath);//listPassPhotos[0].DestImage;
                    if ( !string.IsNullOrEmpty(listUnPassPhotos[0].DestImagePath) && File.Exists(listUnPassPhotos[0].DestImagePath))
                        pictureBox2.Image = Image.FromFile(listUnPassPhotos[0].DestImagePath); //listPassPhotos[1].DestImage;

                    dicMapToPhoto.Add(pictureBox1, listPassPhotos[0]);
                    dicMapToPhoto.Add(pictureBox2, null);

                    radioButton1.Checked = true;
                    pictureBoxPass.Visible = true;
                    pictureBoxPass.Parent = pictureBox1;
                    pictureBoxPass.Location = new Point(0, 0);

                    pictureBoxNoPass.Visible = true;
                    pictureBoxNoPass.Parent = pictureBox2;
                    pictureBoxNoPass.Location = new Point(0, 0);
                    return;
                }
                // 第一张不合格
                else if (listUnPassPhotos[0].Index == 0)
                {
                    labelDetRes1.Text = "不合格";
                    labelDetRes2.Text = "合格";
                    int x1 = pictureBox1.Left;
                    int y = labelDetRes1.Bottom + 5;
                    Log.WriteAsync($"labelDetRes1位置:({labelDetRes1.Left},{labelDetRes1.Top},{labelDetRes1.Right},{labelDetRes1.Bottom})");
                    label3.Location = new Point(x1, y);
                    int x2 = label3.Right;          
                    labelReason.Location = new Point(x2, y);
                    Log.WriteAsync($"labelReason:({labelReason.Left},{labelReason.Top},{labelReason.Right},{labelReason.Bottom})");
                    
                   
                        if (!string.IsNullOrEmpty(listUnPassPhotos[0].DestImagePath) && File.Exists(listUnPassPhotos[0].DestImagePath))
                            pictureBox1.Image = Image.FromFile(listUnPassPhotos[0].DestImagePath);//listPassPhotos[0].DestImage;

                        if (!string.IsNullOrEmpty(listPassPhotos[0].DestImagePath) && File.Exists(listPassPhotos[0].DestImagePath))
                            pictureBox2.Image = Image.FromFile(listPassPhotos[0].DestImagePath); //listPassPhotos[1].DestImage;
                   
                   


                    dicMapToPhoto.Add(pictureBox1, null);
                    dicMapToPhoto.Add(pictureBox2, listPassPhotos[0]);                   

                    radioButton2.Checked = true;
                    pictureBoxPass.Visible = true;
                    pictureBoxPass.Parent = pictureBox2;
                    pictureBoxPass.Location = new Point(0, 0);

                    pictureBoxNoPass.Visible = true;
                    pictureBoxNoPass.Parent = pictureBox1;
                    pictureBoxNoPass.Location = new Point(0, 0);
                }
            }
        }

        private void SetSelectPhoto(int index)
        {
            if(index > 2 || index < 0)
            {
                throw new Exception("无效的输入参数: 对于SetSelectPhoto，index > 2 || index < 0 ");
            }
            if (takenResultType == PhotoTakenResult.Success)           
            {
                listRadioButtons[index].Checked = true;
                pictureBoxPass.Parent = dicMapToPic[listRadioButtons[index]];
                pictureBoxPass.Visible = true;
                pictureBoxPass.Location = new Point(0, 0);
            }            
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            SetSelectPhoto(0);
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            SetSelectPhoto(1);
        }

        protected override void btnCancel_Click(object sender, EventArgs e)
        {
            ClearData();
            _board.StopWorking();
            NotifyClientTakePhotoCancell();
            Process.ToHome();           
        }

        private void NotifyClientTakePhotoCancell()
        { 
            if (Process.Job != null)
            {
                Process.Job.Cancel("用户选择了取消拍照.");
            }
        }

        private void buttonRetake_Click(object sender, EventArgs e)
        {
            ClearData();
            Process.RemoveKey("PhotoTakenResult");
            Process.RemoveKey("TakenPhotos");
            Process.RemoveKey("NoPassPhotos");
            Process.ToAny("IPCPages.PageShowPreviewTips");//重拍时重新测量身高
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            buttonOK.Enabled = false;
            try
            {
                UpdateData();
                ClearData();
                _board.StopWorking();
                Process.ToNext();
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存照片发生了异常!\n" + ex.Message);
                Log.WriteException(ex.ToString());
                buttonOK.Enabled = true;
                return;
            }          
        }

        public override void OnCountdownCompleted(object sender, EventArgs e)
        {
            _board.StopWorking();
            if (Process.Job != null)
            {
                Process.Job.Cancel("倒计时结束，选照片操作未完成，取消拍照.");
            }
            base.OnCountdownCompleted(sender, e);          
        }

        public override void StartWork()
        {
            Speak("请点击屏幕选择一张更满意的照片");  
        }
    }
}
